/*
 * paymentDAO.java
 *
 * Created on March 17, 2007, 2:14 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.mystuff;

import java.util.*;
import java.sql.*;

/**
 *
 * @author Sam Griffiths
 */
public class storeDAO {
    
    //initialize variables
    private static storeDAO instance;
    private String storeid;
    private static Cache cache;
    
    /** Creates a new instance of paymentDAO */
    public storeDAO() {
    cache = Cache.getInstance();
    }
        
    //returns an instance of StoreDAO
    public static synchronized storeDAO getInstance() {
        if (instance == null) {
            instance = new storeDAO();
            
        }
        return instance;
    }
    
    //creates a new storeBO with id initialized
    public storeBO create(){
        storeid = Guid.generate();
        storeBO str = new storeBO(storeid);
        cache.put(storeid, str);
        return str;
    }
    
    /*
     *This method reads all stores from the database and returns
     *them in an ArrayList
     */
    public synchronized ArrayList<storeBO> readALL() throws DataException {
        ArrayList<storeBO> strlist = new ArrayList();
        Connection conn = null;
        try {
            //getConnection, create an sql statement, execute the Query
            conn = ConnectionPool.getInstance().get();
            //System.out.println("Check");
            Statement st = conn.createStatement();
            //System.out.println("Executing Query");
            ResultSet rs = st.executeQuery("SELECT * FROM STORE_TABLE");
            //System.out.println("Execute Succesful");
            
            while(rs.next()){
                //creates storeBO's from resultset and adds them to strlist (the arraylist)'
                storeBO str = new storeBO(rs.getString("STORE_ID"));
                str.setManagerId(rs.getString("MANAGER"));//artist
                str.setAddress(rs.getString("ADDRESS"));//album
                str.setPhone(rs.getString("PHONE"));
                str.setAlreadyInDatabase(true);
                strlist.add(str);
            }
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return strlist;
    }
    
    //Creates a connection, calls another read method, hands in connection, and storeid
    //returns store object
    public synchronized storeBO read(String storeid) throws DataException{
        storeBO str = null;
        Connection conn = null;
        try {
            conn = ConnectionPool.getInstance().get();
            if(cache.containsKey(storeid))
                str = (storeBO)cache.get(storeid);
            else
                str = read(conn, storeid);
            
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return str;
    }
    
    //exactly like ReadAll, but only reads in one object
    public synchronized storeBO read(Connection conn, String id){
       storeBO str = null;
        try{
        Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM STORE_TABLE WHERE STORE_ID='"+id+"'");
            str = new storeBO(id);
            while(rs.next()){
                
                str.setManagerId(rs.getString("MANAGER"));//artist
                str.setAddress(rs.getString("ADDRESS"));//album
                str.setPhone(rs.getString("PHONE"));
                str.setAlreadyInDatabase(true);
                            
            }
       }catch(Exception e){}
       cache.put(id, str);
       return str;
    }
    
    /////////////save////////////////////
    //calls another save after checking the dirty first to make sure someones not tryingt to resave something and
    //waste precious processing time
    public synchronized boolean save(storeBO str) throws DataException {
       System.out.println("Save entrance accessed");
        Connection conn = null;
        try {
            
            conn = ConnectionPool.getInstance().get();
            if(str.isDirty())
                save(conn,str);
            str.setDirty(false);
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return true;
        }
    
    //checks object to see if it is already is in the database
    //if object is already in database, run an update
    //if object is not in database, run an insert
    public synchronized void save(Connection conn, storeBO str){
        System.out.println("Second Save Accessed");
        try{
            Statement st = conn.createStatement();
           
            //System.out.println("First Query Skipped");
            if(false == str.isAlreadyInDatabase()){
                
                String queryString = "INSERT INTO STORE_TABLE VALUES (?,?,?,?)";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
               
                //String aString = Double.toString(aDouble);
                pstmt.setString(1,str.getStoreId());
                pstmt.setString(2,str.getManagerId());
                pstmt.setString(3,str.getAddress());
                pstmt.setString(4,str.getPhone());
                pstmt.execute();
                pstmt.close();
                str.setAlreadyInDatabase(true);
            } else{
            
                String queryString = "UPDATE STORE_TABLE SET MANAGERID = ?, ADDRESS = ? , PHONE = ? WHERE STORE_ID = ? ";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
                pstmt.setString(1,str.getManagerId());//name
                pstmt.setString(2,str.getAddress());
                pstmt.setString(3,str.getPhone());
                pstmt.setString(4,str.getStoreId());
                pstmt.execute();
                pstmt.close();
                
            }
        }catch(Exception e){}
    }
    
    /////////////delete////////////////////////
    // ya we're not going to delete stores, if we go out of business, we won't need a delete anyways'
    
}
